#pragma once

#include <cstdio>
#include "../gl/Application.h"
#include "GL/glxmd.h"
#include "view.h"

class StlApplication: public GlApplication {
private:
    View * view;
    bool moving = false;
    int m_start_x, m_start_y;
public:

    StlApplication(int argc, char **argv) : GlApplication(argc, argv, false) {
        this->view = new View();
    }

    ~StlApplication() {
        delete this->view;
    }

    void draw() override {
        view->draw();
    }

    void on_timer(int id) override {
        this->view->inc_rotation();
        this->init_timer(0, 50);
        glutPostRedisplay();
    }

    void on_key_down(int key, bool spec, int x, int y) override {
    }

    virtual void on_mouse(int button, int state, int x, int y) {
        if (state==0) switch (button) {
            case 4: //W_F
                this->view->inc_translate(true);
                break;
            case 3: { //W_b
                this->view->inc_translate(false);
                break;
            }
            case 2: {
                this->view->move(0, 0);
                m_start_x = x;
                m_start_y = y;
                this->moving = true;
                break;
            }
                //
        }
        if (state==1) switch (button) {
            case 2: {
                this->view->commit_move();
                this->moving = false;
                break;
            }
        }
        printf("%d %d %d %d\n", button, state, x, y);
    }

    void on_motion(int x, int y) override {
        if (this->moving)
            this->view->move(x - m_start_x, y - m_start_y);
    }


    void run() override{
        GlApplication::run();
    }
protected:

    void pre_loop() override {
        this->init_timer(0, 100);
    }

    void create_scene() override {
        glClearDepth(1.0f);                   // Set background depth to farthest
        glShadeModel(GL_SMOOTH);   // Enable smooth shading
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  // Nice perspective corrections
        // цвет фона
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // Set background color to black and opaque
        // рассчет освещения
        glEnable(GL_LIGHTING);
        // двухсторонний расчет освещения
        glLightModelf(GL_LIGHT_MODEL_TWO_SIDE, GL_TRUE);
        // автоматическое приведение нормалей к
        // единичной длине
        glEnable(GL_NORMALIZE);

        glClearDepth(1.0f);                   // Set background depth to farthest
        glEnable(GL_DEPTH_TEST);   // Enable depth testing for z-culling
        glDepthFunc(GL_LEQUAL);    // Set the type of depth-test
        glShadeModel(GL_SMOOTH);   // Enable smooth shading
        //glfwWindowHint(GLFW_SAMPLES, 4);
        glEnable(GL_MULTISAMPLE);
        view->init();
    }


    GlWindow * createWindow() override {
        auto * window = new GlWindow(800, 200, 800, 800, "Cube");
        return window;
    }

    void releaseResources() override {
    }

    void createResources() override {
    }

};
